package org.test.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component // spring帮助我new出这个对象
@Aspect // 并且将这个类设置为警察
public class ErrorLogAop {

//	private Logger logger = Logger.getLogger(ErrorLogAop.class);

	// 盘查的面（service的所有方法）
	// @Before: 在执行service方法之前就开始盘查
	/**
	 * execution() -> 固定写法 public * com.ctc.ServiceImpl.*.*(..)) -> public:
	 * 盘查的方法是public修饰的 -> * : 返回值的全限定名或* ，这里的*代表随便 -> 包名称用点隔开，如果是需要所有的包，那么就用 * ->
	 * 类名用点和包名隔开，如果是需要所有的类，那么就用 * -> 方法名，如果是需要所有的方法，那么就用 * -> () 代表执行的方法 -> ..
	 * 代表方法的参数随意，
	 */
	@Before("execution(public * org.test.service.*.*(..))")
	public void before() {
		System.out.println("执行事务before");
	}

	@After("execution(public * org.test.service.*.*(..))")
	public void after() {
		System.out.println("执行事务after");
	}

	// around:环绕，在执行代码的前后进行盘查
	@Around("execution(public * org.test.service.*.*(..))")
	public Object around(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("DeclaringType:" + pjp.getSignature().getDeclaringType()); // 盘查的类的class对象
		System.out.println("getName:" + pjp.getSignature().getName()); // 方法名称
		System.out.println("DeclaringTypeName:" + pjp.getSignature().getDeclaringTypeName()); // 盘查的类全限定名
		System.out.println("Kind:" + pjp.getKind()); // 访问方式
		System.out.println("Target:" + pjp.getTarget()); // 类的对象
		try {
			Object obj = pjp.proceed(); // 执行盘查的方法
			return obj;
		} catch (Exception ex) {
			ex.printStackTrace(); // 打印出红色的字体
			// 记录错误日志
//			logger.error(ex.getMessage());
			throw ex; // 叫service层做出回滚
		}
	}
}
